﻿namespace YnabCsvConverter.Core.Converters
{
   using System;
   using System.Collections.Generic;
   using System.Diagnostics;
   using System.Linq;
   using System.Reflection;

   /// <summary>
   /// Scan assembly for converters
   /// </summary>
   public class ConverterScanner
   {
      /// <summary>
      /// Initializes a new instance of the <see cref="ConverterScanner"/> class.
      /// </summary>
      public ConverterScanner()
      {
      }

      /// <summary>
      /// Scan the assembly for all Converters
      /// </summary>
      public List<ConverterItem> ScanAssemblyForConverters()
      {
         var converters = new List<ConverterItem>();

         try
         {
            Assembly assembly = Assembly.GetExecutingAssembly();

            foreach (Type type in assembly.GetTypes())
            {
               if (type.IsClass && !type.IsInterface && !type.IsAbstract)
               {
                  Type[] interfaces = type.GetInterfaces();

                  if (interfaces.SingleOrDefault<Type>(x => x.Name.Equals(typeof(IConverter).Name)) != null)
                  {
                     converters.Add(CreateConverterItem(type));
                  }
               }
            }          
         }
         catch (Exception ex)
         {
            Debug.WriteLine(ex.Message);
         }

         converters.Sort((x, y) => string.Compare(x.Name, y.Name));

         return converters;
      }

      /// <summary>
      /// Creates the converter item.
      /// </summary>
      /// <param name="type">The type.</param>
      private ConverterItem CreateConverterItem(Type type)
      {
         var converterItem = new ConverterItem
         {
            Converter = (IConverter) Activator.CreateInstance(type)
         };


         // Get converter attributes and add info to item.
         Attribute[] attrs = Attribute.GetCustomAttributes(type); 

         foreach (var attribute in attrs)
         {
            var nameAttribute = attribute as ConverterNameAttribute;

            if (nameAttribute != null)
            {
               converterItem.Name = nameAttribute.Name;
            }

            var authorAttribute = attribute as ConverterAuthorAttribute;

            if (authorAttribute != null)
            {
               converterItem.Author = string.Format("by {0}",authorAttribute.Author); 
            }
         }

         return converterItem;
      }
   }
}
